#include "gofgame/common/graphics/LinearGradientBrush.h"

using namespace gofgame::common::graphics;

LinearGradientBrush::LinearGradientBrush(
	const ccColor4F &startColor, 
	const ccColor4F &endColor,
	LinearGradientDirection linearGradientDirection) {
	this->startColor = startColor;
	this->endColor = endColor;
	this->linearGradientDirection = linearGradientDirection;
}

LinearGradientBrush::LinearGradientBrush(
	float beginR, float beginG, float beginB, float beginA,
	float endR, float endG, float endB, float endA,
	LinearGradientDirection linearGradientDirection)
{
	this->startColor.r = beginR;
	this->startColor.g = beginG;
	this->startColor.b = beginB;
	this->startColor.a = beginA;
	this->endColor.r = endR;
	this->endColor.g = endG;
	this->endColor.b = endB;
	this->endColor.a = endA;
	this->linearGradientDirection = linearGradientDirection;
}

LinearGradientBrush *LinearGradientBrush::getInversedBrush() const {
	return new LinearGradientBrush(this->endColor, this->startColor, this->linearGradientDirection);
}

bool LinearGradientBrush::isTransparent() const {
	return this->startColor.a == 0 && this->endColor.a == 0;
}

LinearGradientDirection LinearGradientBrush::getLinearGradientDirection() const {
	return this->linearGradientDirection;
}

const ccColor4F &LinearGradientBrush::getStartColor() const {
	return this->startColor;
}

const ccColor4F &LinearGradientBrush::getEndColor() const {
	return this->endColor;
}

void LinearGradientBrush::onFillRect(float left, float top, float width, float height) {
	GLfloat vertexArr[8];
	if (this->linearGradientDirection == LinearGradientDirection_Vertical) {
		vertexArr[0] = left;
		vertexArr[1] = top;
		vertexArr[2] = left + width;
		vertexArr[3] = top;
		vertexArr[4] = left;
		vertexArr[5] = top + height;
		vertexArr[6] = left + width;
		vertexArr[7] = top + height;
	} else {
		vertexArr[0] = left + width;
		vertexArr[1] = top;
		vertexArr[2] = left + width;
		vertexArr[3] = top + height;
		vertexArr[4] = left;
		vertexArr[5] = top;
		vertexArr[6] = left;
		vertexArr[7] = top + height;
	}
	ccColor4F sClr = this->getStartColor();
	ccColor4F eClr = this->getEndColor();
	GLfloat colorArr[] = {
		eClr.r, eClr.g, eClr.b, eClr.a,
		eClr.r, eClr.g, eClr.b, eClr.a,
		sClr.r, sClr.g, sClr.b, sClr.a,
		sClr.r, sClr.g, sClr.b, sClr.a,
	};
	CCGLProgram *program = CCShaderCache::sharedShaderCache()->programForKey(kCCShader_PositionColor);
	program->use();
	program->setUniformsForBuiltins();
	ccGLEnableVertexAttribs( kCCVertexAttribFlag_Position | kCCVertexAttribFlag_Color);
    glVertexAttribPointer(kCCVertexAttrib_Position, 2, GL_FLOAT, GL_FALSE, 0, vertexArr);
	glVertexAttribPointer(kCCVertexAttrib_Color, 4, GL_FLOAT, GL_FALSE, 0, colorArr);
	glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}